using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace Terra.Core.Common.Utils;

/// <summary>
/// 验证工具类
/// </summary>
public static class ValidationUtils
{
    #region 基础验证

    /// <summary>
    /// 验证字符串不能为空
    /// </summary>
    /// <param name="input">输入字符串</param>
    /// <returns>验证结果</returns>
    public static bool IsNotEmpty(string input)
    {
        return !string.IsNullOrWhiteSpace(input);
    }

    /// <summary>
    /// 验证字符串长度是否在指定范围内
    /// </summary>
    /// <param name="input">输入字符串</param>
    /// <param name="minLength">最小长度</param>
    /// <param name="maxLength">最大长度</param>
    /// <returns>验证结果</returns>
    public static bool IsLengthBetween(string input, int minLength, int maxLength)
    {
        if (string.IsNullOrEmpty(input))
            return false;
        return input.Length >= minLength && input.Length <= maxLength;
    }

    /// <summary>
    /// 验证数值是否在指定范围内
    /// </summary>
    /// <param name="value">输入数值</param>
    /// <param name="min">最小值</param>
    /// <param name="max">最大值</param>
    /// <returns>验证结果</returns>
    public static bool IsInRange<T>(T value, T min, T max) where T : IComparable<T>
    {
        return value.CompareTo(min) >= 0 && value.CompareTo(max) <= 0;
    }

    #endregion

    #region 业务验证

    /// <summary>
    /// 验证手机号码格式
    /// </summary>
    /// <param name="phoneNumber">手机号码</param>
    /// <returns>验证结果</returns>
    public static bool IsValidPhoneNumber(string phoneNumber)
    {
        if (string.IsNullOrEmpty(phoneNumber))
            return false;
        return Regex.IsMatch(phoneNumber, @"^1[3-9]\d{9}$");
    }

    /// <summary>
    /// 验证电子邮箱格式
    /// </summary>
    /// <param name="email">电子邮箱</param>
    /// <returns>验证结果</returns>
    public static bool IsValidEmail(string email)
    {
        if (string.IsNullOrEmpty(email))
            return false;
        return Regex.IsMatch(email, @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$");
    }

    /// <summary>
    /// 验证身份证号码格式
    /// </summary>
    /// <param name="idNumber">身份证号码</param>
    /// <returns>验证结果</returns>
    public static bool IsValidIdNumber(string idNumber)
    {
        if (string.IsNullOrEmpty(idNumber))
            return false;
        return Regex.IsMatch(idNumber, @"^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$");
    }

    /// <summary>
    /// 验证URL格式
    /// </summary>
    /// <param name="url">URL地址</param>
    /// <returns>验证结果</returns>
    public static bool IsValidUrl(string url)
    {
        if (string.IsNullOrEmpty(url))
            return false;
        return Uri.TryCreate(url, UriKind.Absolute, out _);
    }

    #endregion

    #region 通用验证

    /// <summary>
    /// 使用正则表达式验证
    /// </summary>
    /// <param name="input">输入字符串</param>
    /// <param name="pattern">正则表达式</param>
    /// <returns>验证结果</returns>
    public static bool IsMatch(string input, string pattern)
    {
        if (string.IsNullOrEmpty(input) || string.IsNullOrEmpty(pattern))
            return false;
        return Regex.IsMatch(input, pattern);
    }

    /// <summary>
    /// 验证枚举值是否定义
    /// </summary>
    /// <typeparam name="T">枚举类型</typeparam>
    /// <param name="value">枚举值</param>
    /// <returns>验证结果</returns>
    public static bool IsEnumDefined<T>(T value) where T : Enum
    {
        return Enum.IsDefined(typeof(T), value);
    }

    /// <summary>
    /// 验证集合是否包含元素
    /// </summary>
    /// <typeparam name="T">集合元素类型</typeparam>
    /// <param name="collection">集合</param>
    /// <returns>验证结果</returns>
    public static bool HasItems<T>(IEnumerable<T> collection)
    {
        return collection != null && collection.GetEnumerator().MoveNext();
    }

    #endregion

    #region 密码验证

    /// <summary>
    /// 验证密码强度
    /// 要求：长度至少8位，必须包含大小写字母、数字和特殊字符
    /// </summary>
    /// <param name="password">待验证的密码</param>
    /// <returns>是否是强密码</returns>
    public static bool ValidatePasswordStrength(string password)
    {
        if (string.IsNullOrEmpty(password) || password.Length < 8)
        {
            return false;
        }

        // 使用单个正则表达式验证所有要求
        var strongPasswordPattern = new Regex(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+\-=\[\]{};':""\\|,.<>/?])[A-Za-z\d!@#$%^&*()_+\-=\[\]{};':""\\|,.<>/?]{8,}$");
        return strongPasswordPattern.IsMatch(password);
    }

    #endregion
}